home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / unarced / graphics / anim / ilbmwx.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  7KB  |  211 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMW.C  Support routines for writing ILBM files.            1/23/86
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * revised for VideoStage animation IFF files by Gary Bonham,
  6.  * Sparta Inc., 15 Aug 86.
  7.  *
  8.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  9.  * This software is in the public domain.
  10.  *
  11.  * This version for the Commodore-Amiga computer.
  12.  *----------------------------------------------------------------------*/
  13. #include "functions.h"
  14. #include "packer.h"
  15. #include "ilbm.h"
  16. #include "stdio.h"
  17.  
  18. #define MAX(a,b) ((a)>(b)?(a):(b))
  19. #define MIN(a,b) ((a)<(b)?(a):(b))
  20.  
  21. extern int Pop;
  22. UBYTE BMmask;
  23.  
  24. /*---------- InitBMHdr -------------------------------------------------*/
  25. IFFP InitBMHdr(bmHdr0, bitmap, masking, compression, transparentColor,
  26.         pageWidth, pageHeight)
  27.         BitMapHeader *bmHdr0;  struct BitMap *bitmap;
  28.         WORD masking;        /* Masking */
  29.     WORD compression;    /* Compression */
  30.     WORD transparentColor;    /* UWORD */
  31.     WORD pageWidth, pageHeight;
  32.     {
  33.     register BitMapHeader *bmHdr = bmHdr0;
  34.     register WORD rowBytes = bitmap->BytesPerRow;
  35.     long maxx,minx,maxy,miny,ip,ib,ir;
  36.  
  37.     bmHdr->w = rowBytes << 3;
  38.     bmHdr->h = bitmap->Rows;
  39.     bmHdr->x = bmHdr->y = 0;    /* Default position is (0,0).*/
  40.     bmHdr->nPlanes = bitmap->Depth;
  41.     bmHdr->masking = masking;
  42.     bmHdr->compression = compression;
  43.     bmHdr->pad1 = 0;
  44.     bmHdr->transparentColor = transparentColor;
  45.     bmHdr->xAspect = bmHdr->yAspect = 1;
  46.     bmHdr->pageWidth = pageWidth;
  47.     bmHdr->pageHeight = pageHeight;
  48.     BMmask = 0xFF;
  49.  
  50.     if (Pop) {
  51.        maxx = 0;
  52.        minx = 10000;
  53.        maxy = 0;
  54.        miny = 10000;
  55.        BMmask = 0;
  56.        for (ip=0;ip<bitmap->Depth;ip++) {
  57.           for (ir=0;ir<bitmap->Rows;ir++) {
  58.              for (ib=0;ib<rowBytes;ib++) {
  59.                 if (*(bitmap->Planes[ip]+ib+ir*rowBytes)) {
  60.                    BMmask |= 1<<ip;
  61.                    maxx = MAX(maxx,ib);
  62.                    minx = MIN(minx,ib);
  63.                    maxy = MAX(maxy,ir);
  64.                    miny = MIN(miny,ir);
  65.                 }
  66.              }
  67.           }
  68.        }
  69.        if (BMmask == 0) {
  70.           minx = 0;
  71.           miny = 0;
  72.           maxx = rowBytes - 1;
  73.           maxy = bitmap->Rows - 1;
  74.        }
  75.        rowBytes = maxx - minx + 1;
  76.        if (rowBytes & 1) {
  77.           rowBytes++;
  78.           if (minx & 1) minx--;
  79.           else          maxx++;
  80.        }
  81.        bmHdr->x = minx << 3;
  82.        bmHdr->y = miny;
  83.        bmHdr->w = rowBytes << 3;
  84.        bmHdr->h = maxy - miny + 1;
  85.     }
  86.  
  87.     if (pageWidth < 400) {
  88.         if (pageHeight < 300) {
  89.            bmHdr->xAspect = x320x200Aspect;
  90.        bmHdr->yAspect = y320x200Aspect;
  91.         }
  92.         else {
  93.            bmHdr->xAspect = x320x400Aspect;
  94.        bmHdr->yAspect = y320x400Aspect;
  95.         }
  96.     }
  97.     else {
  98.         if (pageHeight < 300) {
  99.            bmHdr->xAspect = x640x200Aspect;
  100.        bmHdr->yAspect = y640x200Aspect;
  101.         }
  102.     else {
  103.            bmHdr->xAspect = x640x400Aspect;
  104.        bmHdr->yAspect = y640x400Aspect;
  105.         }
  106.     }
  107.  
  108.     return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY );
  109.     }
  110.  
  111. /*---------- PutCMAP ---------------------------------------------------*/
  112. IFFP PutCMAP(context, colorMap, depth)   
  113.       GroupContext *context;  WORD *colorMap;  UBYTE depth;
  114.    {
  115.    register LONG nColorRegs;   
  116.    IFFP iffp;
  117.    ColorRegister colorReg;
  118.  
  119.    if (depth > 5)   depth = 5;
  120.    nColorRegs = 1 << depth;
  121.  
  122.    iffp = PutCkHdr(context, ID_CMAP
  123.        , (long)(nColorRegs * sizeofColorRegister));
  124.    CheckIFFP();
  125.  
  126.    for ( ;  nColorRegs;  --nColorRegs)  {
  127.       colorReg.red   = ( *colorMap >> 4 ) & 0xf0;
  128.       colorReg.green = ( *colorMap      ) & 0xf0;
  129.       colorReg.blue  = ( *colorMap << 4 ) & 0xf0;
  130.       iffp = IFFWriteBytes(context, (BYTE *)&colorReg
  131.                  , (long)sizeofColorRegister);
  132.       CheckIFFP();
  133.       ++colorMap;
  134.       }
  135.  
  136.    iffp = PutCkEnd(context);
  137.    return(iffp);
  138.    }
  139.  
  140. /*---------- PutBODY ---------------------------------------------------*/
  141. /* NOTE: This implementation could be a LOT faster if it used more of the
  142.  * supplied buffer. It would make far fewer calls to IFFWriteBytes (and
  143.  * therefore to DOS Write). */
  144. IFFP PutBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  145.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  146.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  147.    {         
  148.    IFFP iffp;
  149.    LONG rowBytes = bitmap->BytesPerRow;
  150.    long dstDepth = bmHdr->nPlanes;
  151.    Compression compression = bmHdr->compression;
  152.    long planeCnt;        /* number of bit planes including mask */
  153.    long deltabyte;
  154.    register long iPlane, iRow;
  155.    register LONG packedRowBytes;
  156.    BYTE *buf;
  157.    BYTE *planes[MaxAmDepth + 1]; /* array of ptrs to planes & mask */
  158.  
  159.    deltabyte = (bmHdr->pageWidth>>3) - (bmHdr->w>>3);
  160.  
  161.    if ( bufsize < MaxPackedSize(rowBytes)  ||    /* Must buffer a comprsd row*/
  162.         compression > cmpByteRun1  ||        /* bad arg */
  163.     bitmap->Depth < dstDepth   ||        /* inconsistent */
  164.     dstDepth > MaxAmDepth )            /* too many for this routine*/
  165.       return(CLIENT_ERROR);
  166.  
  167.    planeCnt = dstDepth + (mask == NULL ? 0 : 1);
  168.  
  169.    /* Copy the ptrs to bit & mask planes into local array "planes" */
  170.    for (iPlane = 0; iPlane < dstDepth; iPlane++)
  171.       if ((Pop == 0) || ((BMmask>>iPlane)&1))
  172.          planes[iPlane] = (BYTE *)bitmap->Planes[iPlane]
  173.                      + bmHdr->y * rowBytes + (bmHdr->x>>3);
  174.       else planes[iPlane] = NULL;
  175. #if 0
  176.       printf("plane %ld: %ld %ld\n",iPlane,planes[iPlane],bitmap->Planes[iPlane]);
  177. #endif
  178.    if (mask != NULL) planes[dstDepth] = mask;
  179.  
  180.    /* Write out a BODY chunk header */
  181.    iffp = PutCkHdr(context, ID_BODY, (long)szNotYetKnown);
  182.    CheckIFFP();
  183.  
  184.    /* Write out the BODY contents */
  185.    for (iRow = bmHdr->h; iRow > 0; iRow--)  {
  186.       for (iPlane = 0; iPlane < planeCnt; iPlane++)  {
  187.          if (planes[iPlane]) {
  188.             /* Write next row.*/
  189.             if (compression == cmpNone) {
  190.                iffp = IFFWriteBytes(context, planes[iPlane], (long)rowBytes);
  191.                planes[iPlane] += rowBytes;
  192.             }
  193.  
  194.             /* Compress and write next row.*/
  195.             else {
  196.                buf = buffer;
  197.                packedRowBytes = PackRow(&planes[iPlane], &buf
  198.                       , (long)(bmHdr->w>>3));
  199.                iffp = IFFWriteBytes(context, buffer, (long)packedRowBytes);
  200.                planes[iPlane] += deltabyte;
  201.             }
  202.          }
  203.          CheckIFFP();
  204.       }
  205.    }
  206.  
  207.    /* Finish the chunk */
  208.    iffp = PutCkEnd(context);
  209.    return(iffp);
  210. }
  211.